<template>
  <vue-tinymce v-model="rests"
               ref="tinymce"
               @change="changeEdit"
               :setting="setting"
               :setup="setup" />
</template>

<script>
import mixinViewModule from '@/mixins/view-module'
export default {
  mixins: [mixinViewModule],
  props: {
    isEdit: {
      type: Boolean,
      default: false
    },
    height: {
      type: [Number, String],
      default: 350
    },
    wordLimit: {
      type: Number,
      default: 20000
    },
    placeholder: {
      type: String,
      default: '请输入描述'
    },
    isTabel: {
      type: Boolean,
      default: false
    },
    isMedia: {
      type: Boolean,
      default: true
    },
    noDelete: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      mixinViewModuleOptions: {
        // deleteURL: '/tb/file/delFileOss',
        insertFileURL: '/system/oss/upload'
      },
      verification: true,
      dataListLoading: true,
      rests: '',
      editNewImgList: [], // 在编辑状态下新添加的图片
      editNewVideoList: [], // 在编辑状态下新添加的视频
      imgPaths: [],
      videoPaths: []
    }
  },
  computed: {
    setting () {
      return {
        menubar: false,
        toolbar: `${this.isTabel ? 'table' : ''} | ${this.isMedia ? 'media' : ''} | undo redo | fullscreen | formatselect alignleft aligncenter alignright alignjustify | link unlink | numlist bullist | image | fontselect fontsizeselect forecolor backcolor | bold italic underline | indent outdent | superscript subscript | removeformat `,
        toolbar_drawer: 'sliding',
        media_alt_source: false,
        media_poster: false,
        quickbars_selection_toolbar: 'removeformat | bold italic underline | fontsizeselect forecolor backcolor',
        plugins: 'link image media table lists fullscreen  ax_wordlimit paste table noneditable ',
        language: 'zh_CN', // 本地化设置
        height: this.height,
        placeholder: this.placeholder,
        paste_word_valid_elements: 'img',
        paste_enable_default_filters: true,
        paste_preprocess: this.pastePreprocess,
        ax_wordlimit_num: this.wordLimit,
        ax_wordlimit_event: 'SetContent Undo Redo Keyup blur',
        ax_wordlimit_callback: this.axWordlimitCallback,
        images_upload_handler: this.imagesUploadHandler,
        file_picker_callback: this.filePickerCallback,
        file_picker_types: 'media'
      }
    }
  },
  methods: {
    init (data, imgFiles, videoFiles) {
      imgFiles = imgFiles || ''
      videoFiles = videoFiles || ''
      this.imgPaths = imgFiles === '' ? [] : imgFiles.split(',')
      this.videoPaths = videoFiles === '' ? [] : videoFiles.split(',')
      this.rests = data
    },
    axWordlimitCallback (editor, txt, num) {
      this.verification = false
      this.$message.warning(`当前字数：${txt.length}，限制字数：${num}`)
    },
    pastePreprocess (plugin, args) {
      // 将复制的图片、视频全部过滤掉\
      // eslint-disable-next-line no-useless-escape
      args.content = args.content.replace(/<img\b.*?(?:\>|\/>)/gi, '')
      // eslint-disable-next-line no-useless-escape
      args.content = args.content.replace(/<video\b.*?(?:\>|\/>)/gi, '')
      // eslint-disable-next-line no-useless-escape
      args.content = args.content.replace(/<article\b.*?(?:\>|\/>)/gi, '')
    },
    // 视频上传
    filePickerCallback (callback, value, meta) {
      // 模拟出一个input用于添加本地文件
      const filetype = '.mp4'
      const input = document.createElement('input')
      // const url = 'https://media.w3.org/2010/05/sintel/trailer.mp4'
      const self = this
      input.setAttribute('type', 'file')
      input.setAttribute('accept', filetype)
      input.click()
      input.onchange = function () {
        const file = this.files[0]
        const pattVideo = new RegExp('.(mp4)$', 'i')
        const pattern = /[\u4e00-\u9fa5]+/g

        if (pattern.test(file.name)) {
          self.$message.warning('上传的视频名称不能有中文')
          return
        }

        if (!pattVideo.test(file.name)) {
          self.$message.warning(`上传文件中存在非mp4文件`)
          return false
        }

        self.dataListLoading = true
        const dialogEl = document.getElementsByClassName('tox-dialog')[0]
        const divEl = document.createElement('div')
        divEl.className = 'curtain'
        divEl.innerText = '视频上传中...'
        dialogEl.appendChild(divEl)

        self.downloadImage(file, 1).then(res => {
          dialogEl.removeChild(divEl)
          if (res.code !== 0) {
            this.$message.warning(res.msg)
            return callback()
          }

          // 将编辑时新添加的视频加入对象
          if (self.isEdit) {
            self.editNewVideoList.push(res.data)
          }

          self.videoPaths.push(res.data)
          const url = `${res.data}`
          callback(url)
        })
      }
    },
    // 图片上传
    imagesUploadHandler (blobInfo, succFun, failFun) {
      const file = blobInfo.blob()// 转化为易于理解的file对象
      const isLt5M = file.size / 1024 / 1024 < 5
      const pattern = /[\u4e00-\u9fa5]+/g
      if (pattern.test(file.name)) {
        failFun('上传的图片名称不能有中文')
        return
      }

      if (!isLt5M) {
        failFun(`上传图片的大小不能超过5M`)
        return false
      }

      this.downloadImage(file, 0).then(res => {
        if (res.code !== 0) {
          failFun(res.msg)
          return false
        }

        // 将编辑时新添加的图片加入对象
        if (this.isEdit) {
          this.editNewImgList.push(res.data)
        }

        this.imgPaths.push(res.data)
        succFun(`${res.data}`)
      })
    },
    // 上传接口
    downloadImage (file, type) {
      return this.addOrUpdateItem({ url: this.mixinViewModuleOptions.insertFileURL, paramData: { file: file, bucketName: 'meeting-room/images' }, isJson: false })
    },
    getContent () {
      return this.rests
    },
    setup (editor) {
      const self = this
      editor.on('keyup', function () {
        self.verification = true
      })
    },
    // 获取富文本中图片和视频的路径
    changeEdit () {
      if (this.noDelete) {
        return false
      }
      this.$nextTick(() => {
        if (!tinymce.activeEditor || !tinymce.activeEditor.dom) { return false }
        const els = tinymce.activeEditor.dom.select('img')
        const videoEls = tinymce.activeEditor.dom.select('video')

        this.getEditImage(els)

        this.getEditVideo(videoEls)
      })
    },
    // 获取编辑器中视频地址
    getEditVideo (els) {
      if (!els.length) {
        this.videoPaths = []
      }

      const tempVideoArr = JSON.parse(JSON.stringify(this.videoPaths))
      const tempEditVideo = JSON.parse(JSON.stringify(this.editNewVideoList))
      const newVideoList = []
      const newEditVideoList = []

      els.map(item => {
        // console.log(item)
        const patt = '<source[^<>]*? src="([^<>]*?)"'
        let el = decodeURIComponent(item.innerHTML)

        let src = el.match(patt)[1]
        if (src.indexOf(process.env.VUE_APP_OSS_URL) === -1) { return }
        src = src.split('housekeeper')[1]
        if (src) {
          src = `housekeeper${src}`
          let videoPathIndex = -1
          let editVideoIndex = -1

          // 将编辑器中的视频从videoPaths中剔除出来，剩下的视频路径就是需要删除的视频
          tempVideoArr.map((tempItem, index) => {
            if (tempItem === src) {
              videoPathIndex = index
              newVideoList.push(tempItem)
            }
          })

          // 编辑状态将编辑器中的视频从editNewVideoList中剔除出来，剩下的视频路径就是需要删除的视频
          tempEditVideo.map((editItem, index) => {
            if (editItem === src) {
              editVideoIndex = index
              newEditVideoList.push(editItem)
            }
          })

          if (videoPathIndex !== -1) {
            tempVideoArr.splice(videoPathIndex, 1)
            videoPathIndex = -1
          }

          if (editVideoIndex !== -1) {
            tempEditVideo.splice(editVideoIndex, 1)
            editVideoIndex = -1
          }
        }
      })

      // 将新增时将多余的视频数据删除
      if (tempVideoArr.length && !this.isEdit) {
        // 删除剩余的视频路径
        this.deleteFile(tempVideoArr.join(','))
      }

      // 将编辑时新增的多余视频数据删除
      if (tempEditVideo.length && this.isEdit) {
        this.deleteFile(tempEditVideo.join(','))
      }

      // 重新给videoPaths赋值
      this.videoPaths.splice(0, this.videoPaths.length, ...newVideoList)
      this.editNewVideoList.splice(0, this.editNewVideoList.length, ...newEditVideoList)
    },
    // 获取编辑器中图片地址
    getEditImage (els) {
      if (!els.length) {
        this.imgPaths = []
        // return false
      }

      const tempArr = JSON.parse(JSON.stringify(this.imgPaths))
      const tempEditImg = JSON.parse(JSON.stringify(this.editNewImgList))
      const newImgList = []
      const newEditImgList = []
      els.map(item => {
        if (item.src.indexOf(process.env.VUE_APP_OSS_URL) === -1) { return }
        let src = item.src
        src = src.split('housekeeper')[1]
        if (src) {
          src = `housekeeper${src}`
          let imgPathIndex = -1
          let editImgIndex = -1

          // 将编辑器中的图片从imgPaths中剔除出来，剩下的图片路径就是需要删除的图片

          tempArr.map((tempItem, index) => {
            if (tempItem === src) {
              imgPathIndex = index
              newImgList.push(tempItem)
            }
          })

          // 编辑状态将编辑器中的图片从editNewImgList中剔除出来，剩下的图片路径就是需要删除的图片
          tempEditImg.map((editItem, index) => {
            if (editItem === src) {
              editImgIndex = index
              newEditImgList.push(editItem)
            }
          })

          if (imgPathIndex !== -1) {
            tempArr.splice(imgPathIndex, 1)
            imgPathIndex = -1
          }

          if (editImgIndex !== -1) {
            tempEditImg.splice(editImgIndex, 1)
            editImgIndex = -1
          }
        }
      })

      // 将新增时将多余的图片数据删除
      if (tempArr.length && !this.isEdit) {
        // 删除剩余的图片路径
        this.deleteFile(tempArr.join(','))
      }

      // 将编辑时新增的多余图片数据删除
      if (tempEditImg.length && this.isEdit) {
        this.deleteFile(tempEditImg.join(','))
      }

      // 重新给imgPaths赋值
      this.imgPaths.splice(0, this.imgPaths.length, ...newImgList)
      this.editNewImgList.splice(0, this.editNewImgList.length, ...newEditImgList)
    },
    getImagePath () {
      return this.imgPaths.join(',')
    },
    getVideoPath () {
      return this.videoPaths.join(',')
    },
    deleteFile (url) {
      this.getDataList({ url: this.mixinViewModuleOptions.deleteURL, paramData: { fileName: url }, isLoading: false })
    },
    clearData () {
      this.editNewImgList = []
      this.imgPaths = []
      this.editNewVideoList = []
      this.videoPaths = []
    },
    getVerification () {
      return this.verification
    },
    clear (isSubmit) {
      // 新增时如果表单没有点击提交，就会删除上传的图片和文件
      if (!this.isEdit && this.imgPaths.length && !isSubmit) {
        this.deleteFile(this.imgPaths.join(','))
      }

      if (!this.isEdit && this.videoPaths.length && !isSubmit) {
        this.deleteFile(this.videoPaths.join(','))
      }

      // 修改时如果表单没有点击提交，就会删除上传的图片和文件
      if (this.isEdit && this.editNewImgList.length && !isSubmit) {
        this.deleteFile(this.editNewImgList.join(','))
      }

      if (this.isEdit && this.editNewVideoList.length && !isSubmit) {
        this.deleteFile(this.editNewVideoList.join(','))
      }

      this.clearData()
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep .curtain {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  background-color: white;
}
</style>
